package com.bonc.apicreator.utils;


import java.io.IOException;
import java.io.Writer;

import org.springframework.util.Assert;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;


/**
 * json工具类
 *
 * @author gaopengyu
 * @version 2016年9月29日
 * @see JsonUtils
 * @since
 */
public final class JsonUtils {

    /** ObjectMapper */
    private static ObjectMapper mapper = new ObjectMapper();
    static {
        mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    private JsonUtils() {

    }

    /**
     * Description:将对象转换为JSON字符串
     * 
     * @param value
     * @return String
     * @see
     */
    public static String toJson(Object value) {
        try {
            return mapper.writeValueAsString(value);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Description: 将对象转换为JSON字符串并格式化
     * 
     * @param value
     * @return String
     * @see
     */
    public static String toFormatJson(Object value) {
        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(value);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Description: 将JSON字符串转换为对象
     * 
     * @param json
     * @param typeReference
     * @return T
     * @see
     */
    @SuppressWarnings("unchecked")
    public static <T> T toObject(String json, TypeReference<?> typeReference) {
        Assert.hasText(json);
        Assert.notNull(typeReference);
        try {
            return (T)mapper.readValue(json, typeReference);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Description: 将JSON字符串转换为对象
     * 
     * @param json
     * @param javaType
     * @return T
     * @see
     */
    @SuppressWarnings("unchecked")
    public static <T> T toObject(String json, JavaType javaType) {
        Assert.hasText(json);
        Assert.notNull(javaType);
        try {
            return (T)mapper.readValue(json, javaType);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @name 将对象转换为JSON流
     * @Description
     * @CreateDate 2015年8月21日下午3:01:14
     */
    public static void writeValue(Writer writer, Object value) {
        try {
            mapper.writeValue(writer, value);
        }
        catch (JsonGenerationException e) {
            e.printStackTrace();
        }
        catch (JsonMappingException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Description: 序列化对象
     * 
     * @param o
     * @return byte[]
     * @see
     */
    public static byte[] serializeObject(Object o) {
        try {
            return mapper.writeValueAsBytes(o);
        }
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Description: 根据类型反序列化对象
     * 
     * @param bytes
     * @param type
     * @return T
     * @see
     */
    @SuppressWarnings("unchecked")
    public static <T> T deSerializeObject(byte[] bytes, TypeReference<T> type) {
        try {
            return (T)mapper.readValue(bytes, type);
        }
        catch (JsonParseException e) {
            e.printStackTrace();
        }
        catch (JsonMappingException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}